package com.cy.security.config;

import com.cy.security.config.handler.DefaultAccessDeniedExceptionHandler;
import com.cy.security.config.handler.DefaultAuthenticationEntryPoint;
import com.cy.security.config.handler.RedirectAuthenticationFailureSuccessHandler;
import com.cy.security.config.handler.RedirectAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * 工程启动时有限加载,在配置类中通常会对第三方资源进行初始配置
 * */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration//配置类
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//    super.configure(http)


    @Override
    protected void configure(HttpSecurity http) throws Exception {
//     super.configure(http);
//     1.关闭跨域攻击
        http.csrf().disable();
//     2.配置登录url(登录表单使用哪个页面)
        http.formLogin()
                .loginPage("/login.html")//登录页面
                .loginProcessingUrl("/login")//与form表单中的action值相同

        //      .successForwardUrl("/index.html");//请求转发
        //      .defaultSuccessUrl("/index.html")
                .successHandler(new RedirectAuthenticationSuccessHandler("/index.html"))
        //      .failureUrl("/login?error");//登录失败
                .failureHandler(new RedirectAuthenticationFailureSuccessHandler("/fail.html"));

        //      3.放行登录url(不需要认证就可以访问)

        http.authorizeRequests()
                .antMatchers("index.html",
                        "/js/*",
                        "/css/*",
                        "/bower_components/**",
                        "/login.html",
                        "/images/**",
                        "/fail.html"
                        //"/doCreate"//设置一个用来检验效果
                )//这里写要放行的资源
                .permitAll()//允许直接访问
                .anyRequest().authenticated();//除了以上资源必须认证才可以访问

        //4.配置登出
        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout");//标识一下是从logout过来的

        http.exceptionHandling()
                .authenticationEntryPoint(new DefaultAuthenticationEntryPoint())
                .accessDeniedHandler(new DefaultAccessDeniedExceptionHandler());


    }

    /**
     * 定义SpringSecurity密码加密对象
     *
     * @Bean  注解通常会在@Configuration注解描述的类中描述方法,
     * 用于告诉spring框架这个方法的返回值会交给spring管理,并给
     * 对象起个默认的名字,这个名字与方法名相同,当然也可以通过
     * @Bean注解起名字
     * */






    @Bean("bcryptPasswordEncoder")
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}
